/*
 * dir_monitor.c
 *
 *  Created on: Feb 21, 2011
 *      Author: s126135
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <sys/ioctl.h>

#include "mod_general.h"
#include "../terminals.h"

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int fd;

void* dir_monitor(void* arg) {
	static char str_buffer[4096];
	terminal_t* term = (terminal_t*) arg;
	int res, wd, i;
	char* string;
	struct inotify_event *event;
	char buffer[BUF_LEN];

	str_buffer[4095] = 0;

	while (ioctl(term->pins.terminal_read, FIONREAD, (char*)&res) != -1 && res > 0)
		read(term->pins.terminal_read, str_buffer, 4095);

	terminal_write_to_daemon(term, "variables get CASPER_POOL_DIR");
	string = terminal_read_from_daemon(term);

	fprintf(stderr, "INFO: dir_monitor: listening for files added to pool directory %s\n", string);
	wd = inotify_add_watch(fd, string, IN_CLOSE_WRITE);
	if (res < 0) {
		fprintf(stderr, "ERROR: dir_monitor: unable to watch %s (%d): %s", string, errno, strerror(errno));
		free(string);
		return errno;
	}

	free(string);

	while (1) {
		i = 0;
		res = read(fd, buffer, BUF_LEN);
		while (i < res) {
			event = (struct inotify_event *) &buffer[i];
			if (event != NULL && event->len) {
				if (event->mask & IN_CLOSE_WRITE) {
					if (event->mask & IN_ISDIR) {
						//printf("The directory %s was created.\n", event->name);
					} else {
						fprintf(stderr, "INFO: dir_monitor: added file %s to the pool directory: launching job\n", event->name);
						sprintf(str_buffer, "jobs new %s", event->name);
						terminal_write_to_daemon(term, str_buffer);
					}
				}
			}
			i += EVENT_SIZE + event->len;
		}
	}
}

int module_init(terminal_t* term) {
	pthread_t tid;
	int res;

	fd = inotify_init();

	if (fd < 0) {
		fprintf(stderr, "ERROR: dir_monitor: unable to instantiate inotify (%d): %s\n", errno, strerror(errno));
		return errno;
	}

	res = pthread_create(&tid, NULL, dir_monitor, term);
	if (res != 0) {
		fprintf(stderr, "ERROR: dir_monitor: unable to create thread (pthread_create: %d)\n", res);
		return errno;
	}

	return 0;
}
